package service

import (
	"errors"
	"fmt"
	"gorm.io/gorm"
	"monitor_serve/initialize"
	"monitor_serve/model"
	"time"
)

type FileService struct {
}

type TableFile struct {
	FileSha1 string //通过fileSha1来检查文件是否已经存在
	FileName string
	FileSize int64
	Location string
	UploadAt string
}

// 插入元信息到数据库
func (f *FileService) OnFileUploadFinished(fileSha1 string, fileName string, fileSize int64, location string) error {
	// 开始一个新的事务
	tx := initialize.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 先查找数据库中是否已经存在相同的 FileSha1
	var existingFileInfo model.FileInfo
	result := tx.Where("file_sha1 = ?", fileSha1).First(&existingFileInfo)

	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			// 数据库中没有找到相同的 FileSha1，可以插入新记录
			fileInfo := model.FileInfo{
				FileSha1: fileSha1,
				FileName: fileName,
				FileSize: fileSize,
				FileAddr: location,
			}
			result = tx.Create(&fileInfo)
			if result.Error != nil {
				tx.Rollback()
				// 记录错误日志
				fmt.Println("Failed to insert file info into database:", result.Error)
				return fmt.Errorf("failed to insert file info into database: %w", result.Error)
			}
			// 提交事务
			if err := tx.Commit().Error; err != nil {
				tx.Rollback()
				fmt.Println("Failed to commit transaction:", err)
				return fmt.Errorf("failed to commit transaction: %w", err)
			}
		} else {
			// 处理其他查询错误，例如记录日志或返回错误信息
			tx.Rollback()
			fmt.Println("Failed to query file info from database:", result.Error)
			return fmt.Errorf("failed to query file info from database: %w", result.Error)
		}
	} else {
		// 如果已经存在相同的 FileSha1，则不做任何操作
		fmt.Println("File with the same SHA1 already exists, skipping insertion.")
	}

	return nil
}

// 根据filehash 查询相关信息
func (f *FileService) GetFileMeta(fileHash string) (*TableFile, error) {
	var fileInfo model.FileInfo
	result := initialize.DB.Where("file_sha1 = ?", fileHash).First(&fileInfo)
	if result.Error != nil {
		return nil, result.Error
	}
	formattedUploadAt := fileInfo.UpdatedAt.Format("2006-01-02 15:04:05")
	fileMeta := TableFile{
		FileSha1: fileInfo.FileSha1,
		FileName: fileInfo.FileName,
		FileSize: fileInfo.FileSize,
		Location: fileInfo.FileAddr,
		UploadAt: formattedUploadAt,
	}
	// 如果查询成功，返回 fileMeta 实例
	return &fileMeta, nil
}

// 更新userFile表,插入数据
func (f *FileService) UserFileFinished(username, fileHash, fileName string, fileSize int64) error {
	// 创建 UserFile 实例
	newUserFile := model.UserFile{
		UserName:   username,
		FileSha1:   fileHash,
		FileSize:   fileSize, // 确保文件大小为 int64 类型
		FileName:   fileName,
		UploadAt:   time.Now(), // 设置上传时间为当前时间
		LastUpdate: time.Now(), // 设置最后修改时间为当前时间
		Status:     0,          // 设置文件状态，默认为 0（正常）
	}

	// 插入新记录
	result := initialize.DB.Create(&newUserFile)
	if result.Error != nil {
		// 如果插入失败，返回错误
		return result.Error
	}

	return nil
}

// 根据用户名，查找userFile表信息
func (f *FileService) QueryUserFileMetas(username string) ([]model.UserFile, error) {
	var userFiles []model.UserFile

	// 使用 GORM 构建查询
	result := initialize.DB.Where("user_name = ?", username).Find(&userFiles)

	// 检查查询错误
	if result.Error != nil {
		return nil, result.Error
	}

	// 返回查询结果
	return userFiles, nil
}

// 分页查询根据用户名查询文件信息
func (f *FileService) QueryUserFileByName(username string, offset, pageSize int) ([]model.UserFile, error) {
	var userFiles []model.UserFile
	result := initialize.DB.Where("user_name = ?", username).Order("created_at Desc").Offset(offset).Limit(pageSize).Find(&userFiles)
	// 检查查询错误
	if result.Error != nil {
		return nil, result.Error
	}
	return userFiles, nil
}

// 根据hash更新fileInfo的location
func (f *FileService) UpdateFileInfoLocation(fileHash, destLocation string) error {
	var fileInfo model.FileInfo
	result := initialize.DB.Where("file_sha1 = ?", fileHash).First(&fileInfo)
	if result.Error != nil {
		return result.Error
	}
	fileInfo.FileAddr = destLocation
	if updateResult := initialize.DB.Save(&fileInfo).Error; updateResult != nil {
		return updateResult
	}
	return nil
}
